/*
 * TimeIncrementCalculationStrategy.cpp
 *
 *  Created on: 02/10/2011
 *      Author: godinho
 */

#include <controller/TimeIncrementCalculationStrategy.h>
#include <localview/LocalView.h>
#include <pthread.h>

using namespace localview;

extern "C" void* threadMain(void * arg) {

	TimeIncrementCalculationStrategy* strategy = (TimeIncrementCalculationStrategy*) arg;

	Case* result = strategy->run(strategy->getLocalView(), strategy->getPhaseId(), strategy->getTimestep());

	strategy->setResult(result);

	pthread_exit(0);
}

TimeIncrementCalculationStrategy::TimeIncrementCalculationStrategy() {
	mIsInterrupted = false;

	pthread_attr_init(&mThreadAttrs);
	pthread_attr_setdetachstate(&mThreadAttrs, PTHREAD_CREATE_JOINABLE);

	pthread_mutex_init(&mIsInterruptedMutex, 0);
}

TimeIncrementCalculationStrategy::~TimeIncrementCalculationStrategy() {
	pthread_attr_destroy(&mThreadAttrs);
	pthread_mutex_destroy(&mIsInterruptedMutex);
}

void TimeIncrementCalculationStrategy::start(LocalView* lv, int phaseId, int timestep) {

	mLocalView = lv;
	mPhaseId = phaseId;
	mTimestep = timestep;

	//Creates thread
	pthread_create(&mThreadId, &mThreadAttrs, threadMain, this);
}

void TimeIncrementCalculationStrategy::stop() {

	//TODO check if start was called
	pthread_mutex_lock(&mIsInterruptedMutex);
	mIsInterrupted = true;
	pthread_mutex_unlock(&mIsInterruptedMutex);

	onStop();

	pthread_join(mThreadId, 0);
}

Case* TimeIncrementCalculationStrategy::getResult() {
	//TODO check if start and stop was called
	return mResult;
}

bool TimeIncrementCalculationStrategy::isInterrupted() {
	pthread_mutex_lock(&mIsInterruptedMutex);
	bool returnVal = mIsInterrupted;
	pthread_mutex_unlock(&mIsInterruptedMutex);

	return returnVal;
}

int TimeIncrementCalculationStrategy::getTimestep() {
	return mTimestep;
}

LocalView* TimeIncrementCalculationStrategy::getLocalView() {
	return mLocalView;
}

int TimeIncrementCalculationStrategy::getPhaseId() {
	return mPhaseId;
}

void TimeIncrementCalculationStrategy::setResult(Case* value) {
	mResult = value;
}
